package com.common.config;

import com.common.base.BaseConstant;
import fuhua.com.util.ResultUtil;
import fuhua.com.vo.ExceptionVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.sql.SQLException;


/**
 * 全局异常处理
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionConfig {

    /**
     * 自定义异常
     */
    @ExceptionHandler(value = ExceptionVo.class)
    public ResultUtil processException(ExceptionVo e) {
        log.error("位置:{} -> 错误信息:{}", e.getMethod() ,e.getMessage());
        return ResultUtil.error(e.getCode(),e.getMessage());
    }

    /**
     * 拦截表单参数校验
     */
    @ResponseBody
    @ExceptionHandler(BindException.class)
    public ResultUtil bindExceptionHandler(BindException ex) {
        StringBuffer sb = new StringBuffer();
        BindingResult bindingResult = ex.getBindingResult();
        if (bindingResult.hasErrors()) {
            for (int i = 0; i < bindingResult.getAllErrors().size(); i++) {
                ObjectError error = bindingResult.getAllErrors().get(i);
                sb.append((i == 0 ? "" : "\n") + error.getDefaultMessage());
            }
        }
        return ResultUtil.error(sb.toString());
    }

    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseBody
    public ResultUtil handler(ConstraintViolationException ex) {
        StringBuffer sb = new StringBuffer();
        int i = 0;
        for (ConstraintViolation violation : ex.getConstraintViolations()) {
            sb.append((++i == 1 ? "" : "\n") + violation.getMessage());
        }
        return ResultUtil.error(sb.toString());
    }

    /**
     * 请求方式不支持
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public ResultUtil httpReqMethodNotSupported(HttpRequestMethodNotSupportedException e) {
        log.error("错误信息:{}", e.getLocalizedMessage());
        return ResultUtil.error("请求方式不支持");
    }

    /**
     * 通用异常
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(Exception.class)
    public ResultUtil exception(Exception e) {
        String msg = BaseConstant.UNKNOWN_EXCEPTION;
        if (e instanceof NullPointerException){
            msg = "空指针异常";
        }else if (e instanceof SQLException){
            msg = "SQL异常";
        }
        e.printStackTrace();
        return ResultUtil.error(msg);
    }
}
